package by.kniazhych.core.server.local.rules {
	
	/**
	 * ...
	 * @author Boutylin Mikhail
	 */
	
	import by.kniazhych.core.data.game.PeacePosition;
	import by.kniazhych.core.server.local.ai.TestLogicController;
	import by.kniazhych.core.server.local.events.ServerGameEvent;
	import by.kniazhych.core.server.local.logic.peaces.AbstractPeace;
	import by.kniazhych.core.server.local.data.BoardData;
	import by.kniazhych.core.constants.PeaceType;
	import by.kniazhych.core.constants.UserColor;
	import by.kniazhych.core.server.local.logic.peaces.PeaceLogicFactory;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	

	
	public class Player extends EventDispatcher implements IPlayer{
		;
		
		//--------------------------------------------------------------------------
		//
		//  PROPERTIES
		//
		//--------------------------------------
		protected var _color:uint;
		protected var _data:BoardData;
		protected var _controller:TestLogicController;
		protected const _tron:PeacePosition = new PeacePosition(4, 4);
		
		//--------------------------------------------------------------------------
		//
		//  CONSTRUCTOR
		//
		//--------------------------------------------------------------------------
		
		public function Player(data:BoardData, color:uint) {
			super(this);
			_data = data;
			_color = color;
			_controller = new TestLogicController();
			_controller.updateData(data);
		}
		
		//--------------------------------------------------------------------------
		//
		//  PUBLIC METHODS
		//
		//--------------------------------------------------------------------------
		
		/* INTERFACE by.kniazhych.core.server.local.rules.IPlayer */
		
		public function get isUnderCheck():Boolean {
			if (isUnderRokash) return true;
			if (hasKniazhych) return false;
			var kniazType:uint = (_color == UserColor.WHITE ? PeaceType.WHITE_KNIAZ : PeaceType.BLACK_KNIAZ);
			if (!_data.getPeacesByType(kniazType).length) return false;
			var kniazPosition:PeacePosition = _data.getPeacesByType(kniazType)[0];
			var enemiePositions:Vector.<PeacePosition> = _getEnemyPeacePositions();
			for (var i:int = 0; i < enemiePositions.length; i++) {
				var pos:PeacePosition = enemiePositions[i];
				if (_controller.checkMotionRules(pos, kniazPosition)) {
					return true;
				}
			}
			return false;
		}
		
		public function get isUnderRokash():Boolean {
			var enemiePositions:Vector.<PeacePosition> = _getEnemyPeacePositions();
			if (this.hasNobelOnTron) {
				for (var i:int = 0; i < enemiePositions.length; i++) {
					var pos:PeacePosition = enemiePositions[i];
					if (_controller.checkMotionRules(pos, _tron)) {
						return true;
					}
				}
			}
			
			return false;
		}
		
		public function get hasKniazhych():Boolean{
			var type:uint = (_color == UserColor.WHITE ? PeaceType.WHITE_KNIAZHYCH : PeaceType.BLACK_KNIAZHYCH);
			return Boolean(_data.getPeacesByType(type).length);
		}
		
		public function get hasNobelOnTron():Boolean {
			var tronState:uint = _data.getCellState(new PeacePosition(4, 4));
			if (_color == UserColor.WHITE) {
				return tronState == PeaceType.WHITE_KNIAZ || tronState == PeaceType.WHITE_KNIAZHYCH;
			}else {
				return tronState == PeaceType.BLACK_KNIAZ || tronState == PeaceType.BLACK_KNIAZHYCH;
			}
		}
		
		public function get hasKniaz():Boolean {
			//trace(Boolean(_data.getPeacesByType(_color == UserColor.WHITE ? PeaceType.WHITE_KNIAZ : PeaceType.BLACK_KNIAZ).length));
			return Boolean(_data.getPeacesByType(_color == UserColor.WHITE ? PeaceType.WHITE_KNIAZ : PeaceType.BLACK_KNIAZ).length);
		}
		
		public function declareKniaz():void {
			var kniazType:uint = this._color == UserColor.WHITE ? PeaceType.WHITE_KNIAZ : PeaceType.BLACK_KNIAZ;
			var kniazhychType:uint = this._color == UserColor.WHITE ? PeaceType.WHITE_KNIAZHYCH : PeaceType.BLACK_KNIAZHYCH;
			var temp:Vector.<PeacePosition> = _data.getPeacesByType(kniazhychType);
			if(temp.length){
				var pos:PeacePosition = temp[0];
				_data.changePeace(pos, kniazType);
			}else {
				forfeight();
			}
			
		}
		
		public function get color():uint{
			return _color;
		}
		
		public function hasPeace(type:uint):Boolean {
			return false;
		}
		
		public function get canPromovePawn():Boolean {
			return Boolean(_promotePawnPosition);
		}
		
		public function get missingPeaces():Array{
			var possiblePeaces:Object = UserColor.WHITE == _color ? _getWhiteRepicablePeaces() : _getBlackRepicablePeaces();
			var resultPeaces:Array = [];
			for (var type:String in possiblePeaces) {
				if(_data.getPeacesByType(uint(type)).length != possiblePeaces[type]) {
					resultPeaces.push(type);
				}
			}
			return resultPeaces;
		}
		//--------------------------------------------------------------------------
		//
		//  PRIVATE METHODS
		//
		//--------------------------------------------------------------------------
		
		protected function get _promotePawnPosition():PeacePosition {
			var rowNumber:uint = _color == UserColor.WHITE ? 0 : 8;
			var finalRow:Array = _data.board[rowNumber] as Array;
			var pawnType:uint = _color == UserColor.WHITE ? PeaceType.WHITE_PAWN : PeaceType.BLACK_PAWN;
			for (var i:int = 0; i < finalRow.length; i++) {
				if (finalRow[i] == pawnType) return new PeacePosition(i, rowNumber);
			}
			return null;
		}
		
		private function _getWhiteRepicablePeaces():Object {
			var obj:Object = { };
			obj[PeaceType.WHITE_GARMATA] = 2;
			obj[PeaceType.WHITE_LADZIA] = 2;
			obj[PeaceType.WHITE_VAUKALAK] = 2;
			obj[PeaceType.WHITE_GETMAN] = 1;
			return obj;
		}
		
		private function _getBlackRepicablePeaces():Object {
			var obj:Object = { };
			obj[PeaceType.BLACK_GARMATA] = 2;
			obj[PeaceType.BLACK_LADZIA] = 2;
			obj[PeaceType.BLACK_VAUKALAK] = 2;
			obj[PeaceType.BLACK_GETMAN] = 1;
			return obj;
		}
		
		private function _getEnemyPeacePositions():Vector.<PeacePosition> { //TODO:change to cashed getter
			var result:Vector.<PeacePosition> = new Vector.<PeacePosition>();
			var enemyPeacesType:Array = _color == UserColor.WHITE ? PeaceType.BLACK_PEACES : PeaceType.WHITE_PEACES;
			for (var i:int = 0; i < enemyPeacesType.length; i++) {
				var temp:Vector.<PeacePosition> = _data.getPeacesByType(enemyPeacesType[i]);
				result = result.concat(temp);
			}
			return result;
		}
		
		/* INTERFACE by.kniazhych.core.server.local.rules.IPlayer */
		
		public function chosePeace():void{
			
		}
		
		/* INTERFACE by.kniazhych.core.server.local.rules.IPlayer */
		
		public function selectPeace(type:uint):void{
			if (!_promotePawnPosition) return;
			_data.changePeace(_promotePawnPosition, type);
		}
		
		/* INTERFACE by.kniazhych.core.server.local.rules.IPlayer */
		
		public function forfeight():void{
			super.dispatchEvent(new ServerGameEvent(ServerGameEvent.FORFEIGHT));
		}
	}

}